package cc.eevee.jni.libsamples;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class HiSurfaceView2 extends SurfaceView implements SurfaceHolder.Callback {

  private DrawThread mDrawThread;
  private Painter mPainter;

  public HiSurfaceView2(Context context) {
    super(context);
    initHiSurfaceView(context);
  }

  public HiSurfaceView2(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public HiSurfaceView2(Context context, AttributeSet attrs, int defStyleAttr) {
    this(context, attrs, defStyleAttr, 0);
  }

  public HiSurfaceView2(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    initHiSurfaceView(context);
  }

  private void initHiSurfaceView(Context context) {
    getHolder().addCallback(this);
    mPainter = new Painter(context);
  }

  private void startDrawThread() {
    if (mDrawThread != null) return;
    mDrawThread = new DrawThread(getHolder(), new OnDrawListener() {
      @Override public void onDraw(Canvas canvas) {
        HiSurfaceView2.this.drawHi(canvas);
      }
    });
    mDrawThread.start();
  }

  private void stopDrawThread() {
    if (mDrawThread == null) return;
    mDrawThread.cancel();
    mDrawThread = null;
  }

  @Override
  public void surfaceCreated(SurfaceHolder holder) {
    holder.setFormat(PixelFormat.TRANSLUCENT);
    startDrawThread();
  }

  @Override
  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
  }

  @Override
  public void surfaceDestroyed(SurfaceHolder holder) {
    stopDrawThread();
  }

  public void drawHi(Canvas canvas) {
    final Rect rect = new Rect(0, 0, canvas.getWidth(), canvas.getHeight());

    //canvas.drawColor(Color.WHITE);
    canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);

    mPainter.drawText(canvas, "Hi", rect, Gravity.CENTER);
  }

  private interface OnDrawListener {
    void onDraw(Canvas canvas);
  }

  private static class DrawThread extends Thread {

    private volatile Thread mBlinker;
    private SurfaceHolder mHolder;
    private OnDrawListener mOnDrawListener;

    public DrawThread(SurfaceHolder holder, OnDrawListener listener) {
      if (listener == null) {
        throw new RuntimeException("OnDrawListener must not be null");
      }
      mHolder = holder;
      mOnDrawListener = listener;
    }

    @Override
    public synchronized void start() {
      mBlinker = this;
      super.start();
    }

    public void cancel() {
      mBlinker = null;
    }

    @Override
    public void run() {
      Thread thisThread = Thread.currentThread();
      while (mBlinker == thisThread) {
        Canvas canvas = mHolder.lockCanvas();
        if (canvas != null) {
          mOnDrawListener.onDraw(canvas);
          mHolder.unlockCanvasAndPost(canvas);
        }
      }
    }
  }

  private static class Painter {

    private Context mContext;
    private TextPaint mPencil = new TextPaint();

    public Painter(Context context) {
      mContext = context;
      reset();
    }

    public void reset() {
      resetPencil();
    }

    public void resetPencil() {
      mPencil.reset();
      mPencil.setAntiAlias(true);
      mPencil.setStyle(Paint.Style.FILL);
      mPencil.setTypeface(Typeface.DEFAULT);
      mPencil.setTextAlign(Paint.Align.LEFT);
      mPencil.setTextSize(dip2px(mContext, 12));
      mPencil.setColor(Color.MAGENTA);
    }

    public TextPaint getPencil() {
      return mPencil;
    }

    public void drawText(Canvas canvas, String text, Rect container, int gravity) {
      drawText(canvas, text, container, gravity, mPencil);
    }

    public void drawText(Canvas canvas, String text, Rect container, int gravity, TextPaint paint) {
      final Rect rect = new Rect();
      paint.getTextBounds(text, 0, text.length(), rect);
      Paint.FontMetrics fontMetrics = paint.getFontMetrics();
      final int height = (int) (fontMetrics.bottom - fontMetrics.top);
      Gravity.apply(gravity, rect.width(), height, container, rect);
      canvas.drawText(text, rect.left, rect.top - fontMetrics.top, paint);
    }

    public float dip2px(Context context, float dip) {
      return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip,
          context.getResources().getDisplayMetrics());
    }
  }

}
